package org.baicaixiaozhan.tenet.reflection.aop.interceptor;

import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import org.baicaixiaozhan.tenet.reflection.aop.Advice;

import java.io.Serializable;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;

/**
 * DESC: 通过 {@link MethodInterceptor} 接口简单实现 Cglib 版的 MethodInterceptor
 *
 * @author : baicaixiaozhan
 * @since : 1.0.0
 */
public class SimpleCglibInterceptor implements MethodInterceptor, Serializable {

    private final Advice advice;

    public SimpleCglibInterceptor(Advice advice) {
        this.advice = advice;
    }

    /**
     * @param o           被代理的对象（需要增强的对象）
     * @param method      被拦截的方法（需要增强的方法）
     * @param args        方法入参
     * @param methodProxy 用于调用原始方法
     */
    @Override
    public Object intercept(Object o, Method method, Object[] args,
                            MethodProxy methodProxy) throws Throwable {
        final Advice advice = this.advice;
        Object object = null;

        if (advice.interrupt(o, method, args)) {
            return null;
        }
        advice.before(o, method, args);
        if (Modifier.isPrivate(method.getModifiers())) {
            method.setAccessible(true);
        }
        try {
            object = methodProxy.invokeSuper(o, args);
            advice.afterReturning(object, o, method, args);
        } catch (Throwable t) {
            advice.afterThrowing(o, method, args, t);
            throw t;
        } finally {
            advice.after(o, method, args);
        }
        return object;
    }
}
